package com.jmye.coding.juc.future;

import java.util.Arrays;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.concurrent.RecursiveAction;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: jmye
 * @date: 2025/7/4 08:52
 **/

public class ForkJoinPoolToSortTask {

    static class SortTask extends RecursiveAction {

        final long[] array;
        final int lo;;
        final int hi;

        public SortTask(long[] array) {
            this.array = array;
            this.lo = 0;
            this.hi = array.length - 1;
        }

        public SortTask(long[] array, int lo, int hi) {
            this.array = array;
            this.lo = lo;
            this.hi = hi;
        }

        private int partition(long[] array, int lo, int hi){
            long x = array[hi];
            int i = lo - 1;
            for (int j = lo; j < hi; j++) {
                if (array[j] <= x) {
                    i++;
                    swap(array, i, j);
                }
            }
            swap(array, i + 1, hi);
            return i + 1;
        }

        private void swap(long[] array, int i, int j){
            long temp = array[i];
            array[i] = array[j];
            array[j] = temp;
        }

        @Override
        protected void compute() {
            if (lo < hi){
                // 找到分区的元素下标
                int pivot = partition(array, lo, hi);
                // 将数组拆成两个任务
                SortTask left = new SortTask(array, lo, pivot - 1);
                SortTask right = new SortTask(array, pivot + 1, hi);

                left.fork();
                right.fork();

                left.join();
                right.join();
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        long[] array = {5,3,9,1,8,2,7,4,6};
        // 第一个任务
        ForkJoinTask sort = new SortTask(array);
        // 一个线程池
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        // ForkJoinPool 开启多个线程，同时执行子任务
        forkJoinPool.submit(sort);
        // 关闭 ForkJoinPool
        forkJoinPool.shutdown();
        // 等待
        forkJoinPool.awaitTermination(10, TimeUnit.SECONDS);

        System.out.println(Arrays.toString(array));
    }

}
